This invention relates in general to addition of functions to code in object-oriented implementations, and more particularly, to a mechanism for dynamically inserting a function into an existing application executable of an object-oriented computer system at runtime.
Computer software used to control ever increasingly complex processes itself continues to become increasingly complex. Many tools have been developed for assisting a software engineer in the development of such complex software. These tools include compilers, assemblers, linkers, editors and the like, as well as other specific specification and design tools, configuration management tools, language-smart editors and the like.
One of the primary tasks of the software engineer is to analyze application code to determine whether the code operates as desired and if an error is found, to initiate a debugging process. Traditional debugging methods include slow manual processes such as inserting print statements into the software at particular locations so that the values of variables and the like may be checked to determine if they have the expected values. However, such approaches are less than optimal because they result in very high overhead and intrusion on the operation of the code being examined.
As a further consideration, there are unique issues involved in debugging distributed object-oriented systems. The paradigmatic differences in the flow of object-oriented code necessitate alternative methods for debugging. Unlike its linear predecessor, the execution flow of object-oriented programs is less structured since each method call may call methods of a seemingly unrelated object. In traditional programming, the flow of control starts at the top and continues to the bottom unless there are subroutines that are called or loops that alter the flow of the program. The subroutines also follow the same execution rules. In object-oriented programs, the flow is not as obvious. Since the execution of a program is likely to involve many objects, and each object has a number of methods that are used to manipulate the object, it is difficult to determine the flow of control throughout the execution of the program.
Consider the object-oriented environment of FIG. 1. In the diagram, method A is responsible for modifying a value of object 1. Method A calls method B to determine the original value to be modified. Method B calls method C in object 2 to determine values in object 2 that will directly affect the value that method B will return. Method C then calls method D to determine a different value in object 1 that helps to define the relationship between the two objects. Armed with this data, method C can return the value to method B which in turn allows method A to modify the value. As more objects are combined, one can readily see that the call stack becomes increasingly important in debugging not only an error in the current method, but in the execution of all previous methods to determine the state an object was in when the current method was called.
Existing object-oriented tracing methods typically employ macro calls that must be physically added to the code by a programmer, this leaves much room for error and it also means that the method that is not physically modified will not be traced. Further, such macro calls, once inserted, are in the code and must be executed even if one is not interested in tracing. Even with a trace flag check, there will be millions of wasted instructions. Since every routine has the same two macros, tracing will only have an on/off quality which allows the user to turn tracing on for every method or off for every method.
In view of the above, a need exists in the art for a novel mechanism for dynamically inserting a function into an existing application executable of an object-oriented environment which does not require a user to modify the source code, does not require the code to be re-compiled with special options, and which allows a user to specify one or more methods for which the function is to be implemented, and minimizes instructions when the function is inactive.
Briefly summarized, the present invention comprises in one aspect a method for inserting a function into an existing application executable of an object-oriented computer system without recompiling the executable. The method includes: modifying runtime configuration settings to add a setting to specify the function for at least one class of the application executable; and running the application executable using the modified runtime configuration settings and if runtime determines that the function is active for a class of the executable using the modified runtime configuration settings, then dynamically creating a redirection stub to implement the function for the class.
In another aspect, the invention comprises an object-oriented computer system for inserting a function into an application executable without recompiling the application executable. The system includes means for modifying runtime configuration settings for the application executable to add a setting to specify the function for at least one class of the application executable. Further, the system includes means for running the application executable using the modified runtime configuration settings, wherein the means for running includes means for determining whether the function is active for a class of the executable using the modified configuration settings, and means for dynamically creating a redirection stub to insert the function for the class if the function is active for that class.
In still another aspect, an object-oriented computer system is provided for inserting a function into an application executable without recompiling the executable. The system includes a computing unit adapted to modify runtime configuration settings for the application executable to add a setting to specify the function for at least one class of the executable. The computing unit further is adapted to run the application executable using the modified runtime configuration settings and if runtime determines that the function is active for a class of the application executable using the modified configuration settings, then to dynamically create a redirection stub to implement the function for that class.
In a further aspect, an article of manufacture is provided which includes at least one computer usable medium having computer readable program code means embodied therein for causing inserting of a function into an application executable of an object-oriented computer system without recompiling the application executable. The computer readable program code means in the article of manufacture includes computer readable program code means for causing a computer to effect modifying runtime configuration settings to add a setting to specify the function for at least one class of the application executable; and computer readable program code means for causing a computer to effect running the application executable using the modified configuration settings and if runtime determines that the function is active for a class of the application executable, then dynamically creating a redirection stub to implement the function for that class.
To restate, a technique is presented for dynamically modifying class lineage in order to insert a function, such as a trace function, into an existing application executable of an object-oriented computer system. When implemented as a trace function, the technique allows a user tracing the execution of code to identify what methods of a designated class have been run and provides snapshots of the object as it is modified throughout the execution. Since the check is done at class creation time, i.e., runtime, there is no checking done at object creation time. Therefore, if a user is creating multiple objects of a single class and trace is not active, there is no tracing overhead associated with the creation of the object, and there is no overhead associated with the execution of methods in those objects. Likewise, if tracing is only implemented for a few classes, then tracing overhead is only associated with those designated classes.
Since determination is made at execution time and not compile time, the user enjoys the benefits of tracing without requiring modification to the code when tracing is needed and suffers none of the performance overhead when tracing is not needed. Since the code dynamically creates the entry and exit data needed, there is no chance for the user to inject errors when tracing. Further, since the solution enhances (in one embodiment) IBM""s System Object Model""s (SOM""s) traditional strengths, the code is highly extendable and has binary compatibility between releases. The technique is applicable to any user providing object services wishing to inject a function at execution time without effecting performance when the function is unwanted. For example, a user of SOM or CORBA (Common Object Request Broker Architecture) object request brokers or a C++ language environment may employ the invention.